using System;
using System.Collections.Generic;

public interface IRomanNumeralGenerator
{
    String generate(int number);
}

public class Numeral
{
    public string Symbol { get; set; }
    public int Value { get; set; }
}

public class RomanNumeralGenerator : IRomanNumeralGenerator
{
    private List<Numeral> _numerals;

    /// Load in the numerals largest first
    public RomanNumeralGenerator() {
        _numerals = new List<Numeral>();
        _numerals.Add(new Numeral { Symbol = "M", Value = 1000 });
        _numerals.Add(new Numeral { Symbol = "CM", Value = 900 });
        _numerals.Add(new Numeral { Symbol = "D", Value = 500 });
        _numerals.Add(new Numeral { Symbol = "CD", Value = 400 });
        _numerals.Add(new Numeral { Symbol = "C", Value = 100 });
        _numerals.Add(new Numeral { Symbol = "XC", Value = 90 });
        _numerals.Add(new Numeral { Symbol = "L", Value = 50 });
        _numerals.Add(new Numeral { Symbol = "XL", Value = 40 });
        _numerals.Add(new Numeral { Symbol = "X", Value = 10 });
        _numerals.Add(new Numeral { Symbol = "IX", Value = 9 });
        _numerals.Add(new Numeral { Symbol = "V", Value = 5 });
        _numerals.Add(new Numeral { Symbol = "IV", Value = 4 });
        _numerals.Add(new Numeral { Symbol = "I", Value = 1 });
    }

    /// Turn an integer into a roman numeral
    public string generate(int number) {
        if (number < 1 || number > 3999) throw new ArgumentOutOfRangeException("Number must be between 1 - 3999");
        string result = "";
        int process = number;

        foreach (Numeral numeral in _numerals) {
            if (process == 0) break;
            int quotient = process / numeral.Value;

            // If the number can be divided by this numeral then write out the correct quantity of the numeral
            if (quotient > 0) {
                process = process % numeral.Value;
                for (int count = 0; count < quotient; count++)
                    result += numeral.Symbol;
            }
        }

        return result;
    }
}
